home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / sdimage.com / SDIMAGE.DOC < prev    next >
Encoding:
Text File  |  1989-02-14  |  20.9 KB  |  528 lines

  1.                           SDIMAGE V1.03
  2.                          by Michael Day
  3.                      as of 14 February 1989
  4.  
  5.  
  6.      SDImage is a Turbo Pascal unit designed to allow saving  any 
  7. BGI screen to disk. SDImage uses GetImage and PutImage to do  the 
  8. save.  The Program works by using an intermediate buffer to  save 
  9. the image. The size of the buffer is user definable. 
  10.  
  11.  
  12.  
  13. Image Buffer:
  14.    
  15.      There  are 20 image buffers available for use.  At  startup, 
  16. the  buffers  are  not allocated on the  heap,  only  the  buffer 
  17. headers  exist.  This keeps memory usage at a minimum  since  the 
  18. buffers  are  only allocated when they are needed. You  can  also 
  19. release a buffer at any time to pick up the heap space it uses.
  20.  
  21.      You  can either predefine a buffer to the size you want,  or 
  22. the Image buffer will be automatically allocated when the  buffer 
  23. is used. Although 20 buffers should be more than enough for  most 
  24. applications, you can specify more (or fewer) buffers by changing 
  25. the constant "MaxImageBuf" to the desired value. 
  26.  
  27.      Buffers  are used by direct reference in the  command.  This 
  28. makes  buffer usage unambiguous. When a buffer is  referenced  in 
  29. the SaveImage command, it is first checked to see if there is  an 
  30. image  already stored in it. If there is an image in the  buffer, 
  31. it is immediately flushed to disk. 
  32.  
  33.      If  the  buffer  does not have an image in it,  then  it  is 
  34. checked  to see if the buffer has not been allocated yet. If  the 
  35. buffer  has not been allocated, then a buffer of default size  is 
  36. allocated.  Currently the default buffer size is 5000,  but  this 
  37. can  be redefined by changing the constant "MaxRawImage"  to  the 
  38. desired  default buffer size. Alternately, the individual  buffer 
  39. sizes  can  be changed at run time by using  the  "AllocImageBuf" 
  40. function.
  41.  
  42.      Once  a buffer has been assured to be clean and defined,  it 
  43. is  tested to see if the image can completely fit in the  buffer. 
  44. If  the  image can fit in the buffer, then it is  placed  in  the 
  45. buffer and no further action taken. 
  46.  
  47.      If the image cannot be completely placed in the buffer, then 
  48. a  disk save is performed. The image is moved into the buffer  in 
  49. pieces and flushed to disk until then entire image has been saved 
  50. to disk. The buffer is left empty after a disk save.
  51.  
  52.  
  53.  
  54.  
  55.  
  56. Disk Files:
  57.  
  58.      When   an  image  cannot  fit  in  a  buffer  it   will   be 
  59. automatically  saved to disk instead. Alternately, the image  can 
  60. be  forced to always be directed to the disk (see the section  on 
  61. buffer control).
  62.  
  63.      Images  are  referenced  by an image  reference  number  (or 
  64. handle).  You define the image reference number to be  used  with 
  65. SaveImage  or DisplayImage. This number is used to keep track  of 
  66. the image. If you use the same number for an image, then it  will 
  67. normally be overwritten. An exception to this is if the image  is 
  68. in  a  different buffer. There are no checks made to  see  if  an 
  69. image is in another buffer. 
  70.  
  71.      When an image is written to disk, a file is created using  a 
  72. name  built from the image reference number. An image  file  uses 
  73. the  first three letters "SDI" followed by a leading zero  filled 
  74. number which is the reference number that was passed, followed by 
  75. the file extension of ".IMG". 
  76.  
  77.      An  image  file  will  remain on disk  until  it  is  either 
  78. explictly  erased,  or the DisplayImage function is  called  with 
  79. ImgClr  =  true which will cause the image  to  be  automatically 
  80. erased after the image has been displayed.
  81.  
  82.      Because  an  image  will remain  on  disk  unless  explictly 
  83. erased, it can be very easy to clutter up the disk with old image 
  84. files. For this reason it is recommended that you place the image 
  85. files in their own subdirectory. the "SetImagePath" function  has 
  86. been provided for this purpose.
  87.  
  88.      An  advantage  of having images on disk  referenced  by  the 
  89. image  reference  number  is that images can be  created  in  one 
  90. program  and  displayed in another. A disadvantage  is  that  the 
  91. image  is  saved using the BGI GetImage  and  PutImage  functions 
  92. which means that the display must be the same as the display used 
  93. to create the image.
  94.  
  95.      Saving  images  to  disk allows for a  much  smaller  memory 
  96. requirement  within a program to save images. This can be a  real 
  97. boon  when a program grows too large and you are forced  to  find 
  98. ways  to reduce the amount of memory usage. The  disadvantage  is 
  99. that it is much slower to save an image to disk because you  have 
  100. to deal with the physical access time of the disk drive. This can 
  101. cause  some  problems in the sluggishness of  the  display  while 
  102. saving  or displaying images to/from disk. To help relieve  this, 
  103. SDImage uses special effects to make the display look more active 
  104. and thus giving the user a feeling that the computer is  actually 
  105. doing something to the display while it is busy working with  the 
  106. disk.
  107.  
  108.  
  109.  
  110.  
  111. Special Effects:
  112.  
  113.      Displaying images from disk can take a while to perform,  so 
  114. to  help  liven  things  up  some  special  effects  options  are 
  115. provided.
  116.  
  117.      The special effects work in conjunction with disk  accesses. 
  118. When  an  image  is  being read from disk,  it  usually  must  do 
  119. multiple  buffer writes. By controlling where those writes  occur 
  120. on the screen, special effects can be incorporated into the image 
  121. display.  To do this requires that the image be saved  originally 
  122. in the desired format.
  123.  
  124.      Since   the  special  effects  are  tied  directly  to   the 
  125. disk/buffer transfer, special effects are not operational when an 
  126. image stays in the buffer, or when there is only one buffer image 
  127. in  the disk file. Multiple image segments must be used  to  have 
  128. the  proper  special  effects. Since  only  large  images  really 
  129. benifit from special effects this usually is no problem.
  130.  
  131.      Remember,  the smaller the buffer, the smoother the  special 
  132. effect,  but  at the same time the effect will become  slower  as 
  133. well. This can be compensated for by using a ram-disk instead  of 
  134. a hard disk to store the images.
  135.  
  136.      The  Special  effects are controlled by the  "Style"  option 
  137. word  that is passed to the SaveImage function. The  DisplayImage 
  138. function cannot control special effects. The image must be stored 
  139. with the desired effect for it to be active.
  140.  
  141.      The  lower  four  Style bits  control  the  special  effects 
  142. operation. Bit 2 controls whether the image will be displayed  as 
  143. a "Pull" or via an Expand/Merge operation. Bit 1 controls whether 
  144. the image will grow in the Horizontal or vertical direction.  Bit 
  145. 0 controls the edge that the image will grow from, or whether  it 
  146. will expand or merge. Bit 3 is currently unused.
  147.  
  148.  
  149.                        Style
  150.      +---+-----+---------+------+-------------+ 
  151.      |bit|  3  |    2    |  1   |      0      | 
  152.      +---+-----+---------+------+-------------+ 
  153.      | 1 | --- | Xpd/Mrg | Horz | Xpd/Left/Dn | 
  154.      +---+-----+---------+------+-------------+ 
  155.      | 0 | --- |  Pull   | Vert | Mrg/Rght/Up | 
  156.      +---+-----+---------+------+-------------+ 
  157.  
  158.           0=Pull Down
  159.           1=Pull Up
  160.           2=Pull Right 
  161.           3=Pull Left 
  162.           4=Merge Vertical
  163.           5=Expand Vertical
  164.           6=Merge Horizontal
  165.           7=Expand Horizontal
  166.  
  167. Note:  Special effects only operate when the image is  read  from 
  168. the disk, in fact it works because it uses the disk buffering  as 
  169. an inherent part of the effects control. 
  170.  
  171.  
  172.      
  173.  
  174. Buffer Control:
  175.  
  176.      The  upper  four bits of the Style byte control  the  buffer 
  177. operation. Bit 7 controls the Disk, and bit 6 controls the EMS.
  178.  
  179.  
  180.    -->     EMS is not currently supported in SDImage.     <--
  181.  
  182.  
  183.      If bit 7 is on, then the image will always be saved to disk. 
  184. If bit 7 is off, then the image will try to stay in the buffer if 
  185. possible.
  186.  
  187.      Bit 6 is intended for EMS control. The intent is that if Bit 
  188. 6  is on, then the image will be directed to the EMS  instead  of 
  189. disk.  If  bit 6 is off, then the Disk will be  used.  In  either 
  190. case,  bit  7 controls buffering activity. If bit 4 is  on,  then 
  191. the  image  will be compressed using Run Length  Encoding  before 
  192. being saved to disk.
  193.  
  194.  
  195.                       Style
  196.          +---+------+-------+-----+-----+ 
  197.          |bit|  7   |   6   |  5  |  4  | 
  198.          +---+------+-------+-----+-----+ 
  199.          | 1 | Disk |  EMS  | --- | RLE | 
  200.          +---+------+-------+-----+-----+ 
  201.          | 0 | Auto | NoEMS | --- | BIN | 
  202.          +---+------+-------+-----+-----+ 
  203.  
  204.      The image flow is controlled as follows:
  205.  
  206.           $00  -> Buffer -> Disk
  207.           $40  -> Buffer -> EMS -> Disk
  208.           $80  -> Disk
  209.           $C0  -> EMS -> Disk
  210.  
  211.  
  212.      Another mechanism that can be used is to refer to a ram disk 
  213. for  the images instead of a hard disk. This allows  the  special 
  214. effects associated with disk operation to be used as well as  the 
  215. reduced program memory requirements while still keeping as fast a 
  216. file access as possible. And since a ram disk can be installed in
  217. EMS memory, this would be one way to get around the current  lack 
  218. of EMS support in SDImage.
  219.  
  220.  
  221.  
  222. Run Length Encoding:
  223.  
  224.      A  modified inplace RLE encoding scheme is used to  compress 
  225. the  image  in  the  buffer  when  the  Style  RLE  bit  is  set. 
  226. Compressing  the image saves disk space by reducing the  size  of 
  227. the data to be stored. 
  228.  
  229.      The amount of compression varies. Simple single color images 
  230. with  pull  up or pull down will achieve the greatest  amount  of 
  231. compression. Complex multi-colored images with horizontal special 
  232. effects will be the least compressed. Compression will  typically 
  233. vary from 10% to 50% depending on the image.
  234.  
  235.      Using  compression  will slightly slow  down  the  ImageSave 
  236. because  the  image  must be processed  through  the  compression 
  237. routine first. In the provided SDITEST program this results in  a 
  238. ImageSave  slow  down of about one second for  a  complete  cycle 
  239. (eight  images). This can vary though, and in the case of  simple 
  240. pictures  there may be an overall speedup of the save time  since 
  241. not as much disk write time is required.
  242.  
  243.      In  most  cases the compression will actually speed  up  the 
  244. DisplayImage  because  not as much data has to be read  from  the 
  245. disk (a significant portion of the delay when displaying). In the 
  246. SDITEST  program provided this speedup is about one second for  a 
  247. complete  cycle (eight images). For simple images the speedup  of 
  248. reading compressed images can be significant.
  249.  
  250.  
  251.  
  252.  
  253. Buffer Notes:
  254.  
  255.      Although you can define just about any size buffer you wish, 
  256. there  are some limitations. The maximum buffers size is  limited 
  257. to  65521, and the minimum buffer size is limited to one  row  of 
  258. the saved image, or the buffer size of a saved image being read.
  259.  
  260.      If you change the size of a buffer while an image is in  the 
  261. buffer, the buffer will be flushed and the image will be lost.
  262.  
  263.      If a buffer does not exist or is too small for the operation 
  264. it will be automatically resized to an acceptable value.
  265.  
  266.      If  an  image will not fit in the buffer, then  it  will  be 
  267. placed on the disk. If the image is placed on the disk, then  the 
  268. buffer will be left empty at the end of the operation.
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276. Disk Notes:
  277.  
  278.      When  an image is saved to disk a filename is created  based 
  279. on the image reference number. The filename consists of the three 
  280. letters  "SDI", followed by a left zero filled five digit  number 
  281. which is the image reference number used, followed by an filename 
  282. extension of ".IMG". 
  283.  
  284.      Normally  an image will not be placed on the disk unless  it 
  285. cannot  fit  in the image buffer. Sometimes it  is  desirable  to 
  286. create a disk image for later recall in another program or in the 
  287. same  program  at  a later time. A disk save  can  be  forced  by 
  288. setting  bit  4  ($10) of the "Style"  option  in  the  SaveImage 
  289. function. 
  290.  
  291.      Disk  images use one file per image. Because of  this  there 
  292. can be a lot of image files hanging around if there are a lot  of 
  293. images  saved. Because of this it is recommended that the  images 
  294. be  placed  in their own subdirectory. This will have  the  added 
  295. advantage of speeding things up a bit since the directory  search 
  296. won't have all the other program files to deal with.
  297.  
  298.      Disk images will be left on the disk if the "ImgClr"  option 
  299. in the "DisplayImage" function is false. If ImgClr is provided as 
  300. true,  then the image will be erased from the disk after  it  has 
  301. been displayed. 
  302.  
  303.      If  an image file exists on the disk by the  same  reference 
  304. number  then it will be overwritten by the new image when  it  is 
  305. saved.
  306.  
  307.      You should be aware that if you don't delete the image  file 
  308. while  the program is running it will still be on the disk  after 
  309. the  program has been run. This was done purposely so that  image 
  310. files could be created to be read by other programs or at a later 
  311. date  with the same program. This can however cause a clutter  of 
  312. IMG files if you don't pay attention to this.
  313.  
  314.      You  can  remove  a image file by  just  erasing  the  file. 
  315. Alternately  you  can use the DeleteImage function  to  delete  a 
  316. specific image. 
  317.  
  318.      If   an  image  file  is  requested  and  not   found,   the 
  319. DisplayImage function is aborted and returns a false condition.
  320.  
  321.      If  a  image  file cannot be  created,  then  the  SaveImage 
  322. function will be aborted and returns a false condition.
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331. RLE Notes:
  332.  
  333.      The  RLE compression scheme used is a modified  inplace  Run 
  334. Length  Compression. This means that the compression takes  place 
  335. inside the existing data buffer. This has a significant advantage 
  336. since  additional  buffer space is not required  to  perform  the 
  337. compression.
  338.  
  339.      The  modified RLE compression requires that  two  additional 
  340. words  of data be attached to the beginning of each image  record 
  341. saved.  The  two  words  contain  the  physical  length  of   the 
  342. compressed   record,  and  the  offset  into  the  record   where 
  343. compression actually begins. 
  344.  
  345.      The modified RLE does not compress the entire image.  Rather 
  346. it  only  compresses  that  part  of  the  image  which  can   be 
  347. compressed.  This  is done by first searching the  image  to  see 
  348. where  compression can begin. The offset is then stored into  the 
  349. variable  PakStart.  A second routine then  performs  the  actual 
  350. compression starting at the location found. This can speed up the 
  351. actual compression/decompression time since only the compressible 
  352. portion  of  the  image  will  be  compressed/decompressed.   The 
  353. resulting compressed image size is saved in PakSize.
  354.  
  355.      The  compression mechanism used is to scan though the  image 
  356. looking   for  where  the  actual  compression  can  begin.   The 
  357. compression  offset is then saved. The actual compression of  the 
  358. image  is then performed starting at the offset found. The  image 
  359. is compressed by looking at the count of bytes that are the same. 
  360. If  the count is three or less, then no compression is done,  and 
  361. the data is left unchanged. If there are three or more bytes that 
  362. are  the same, then one copy of the byte is stored,  followed  by 
  363. the count of same bytes that were found (max=255), followed by  a 
  364. zero byte to mark that it is a compression packet. 
  365.  
  366.      Because a zero byte is used to mark compression packets, the 
  367. zero  value is always compressed. Which of course means that  for 
  368. one  or two zero byte values an expansion actually occurs sine  a 
  369. compression packet always uses three bytes.
  370.  
  371.      One  additional exception is the last value(s) in the  image 
  372. is always compressed. This is done to make the software  slightly 
  373. easier to write. It eliminates a potential problem that can occur 
  374. if the last values in the image are not enough to compress  (less 
  375. than four), but more than one.
  376.  
  377.      To uncompress the image, it is read into a full sized buffer 
  378. (equal to or greater than the length of the uncompressed  image). 
  379. the  image  is  then  uncompressed starting at  the  end  of  the 
  380. compressed   image.   Decompression  stops  when   the   original 
  381. compression offset is reached. As a side effect of performing the 
  382. docompression inplace, the decompression routine must maintain  a 
  383. three  byte look ahead buffer (in the cpu registers)  to  prevent 
  384. overwriting the compression data it is reading.
  385.  
  386.      Sometimes the image cannot be compressed. An  incompressible 
  387. image  will result in the compression offset pointer being  equal 
  388. to  the  length of the uncompressed image.  When  that  situation 
  389. detected,  the image will not be compressed or decompressed.  The 
  390. header must still be saved though, so in a worst case, the  image 
  391. record will be 4 bytes longer than an image record saved  without 
  392. compression. 
  393.  
  394.      The  compression/decompression is performed in assembler  so 
  395. that  the speed will be as fast as possible. The  three  routines 
  396. used are implemented as INLINE macros. "ScanImg" scans the  image 
  397. buffer  and  returns  the offset  where  compression  can  begin. 
  398. "PakImag"  compresses  the image and returns the  new  compressed 
  399. image length. "UnPakImage" decompresses the image. UnPackImage is 
  400. an INLINE procedure, so there is no return value. 
  401.  
  402.  
  403.      An example compressed image is shown below:
  404.  
  405.  
  406.        - uncompressed -               - compressed -
  407.      0,0,1,0,1,1,1,1,1,1,          0,0,1,0,1,1,1,1,1,1,
  408.      2,3,4,4,5,6,6,6,7,0,          2,3,4,4,5,6,6,6,7,0,
  409.      1,1,1,1,2,3,0,0,4,5,          1,1,1,1,2,3,0,0,4,5,
  410.      6,0,0,0,1,0,0,1,0,1,          6,0,0,0,1,0,0,1,0,1,
  411.      1,1,1,1,1,1,1,1,1,1,          1,10,0,
  412.      2,2,2,2,2,2,2,2,2,2,          2,10,0,   
  413.      0,0,1,0,1,1,1,1,1,1,          0,2,0, 1, 0,1,0, 1,6,0
  414.      2,2,2,2,2,2,1,2,0,3           2,6,0, 1, 2, 0,1,0, 3,1,0
  415.  
  416.  
  417.    RawSize = 80         PakStart = 40         PakSize = 67                
  418.  
  419.  
  420.  
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441. SDImage Functions:
  442.  
  443.  
  444.  
  445. AllocImageBuf(Buf:word; Size:word):boolean
  446.  
  447.      Allocates  a specified amount of heap memory to the  buffer. 
  448. The buffer is automatically allocated to the default size if  you 
  449. don't  allocate  the buffer before use. You  can  reallocate  the 
  450. buffer size at anytime. If the buffer number is invalid, or there 
  451. is  not enough heap space to allocated the specified  buffer  the 
  452. function will return false. 
  453.  
  454.  
  455.  
  456.  
  457. ReleaseImageBuf(Buf:word):boolean
  458.  
  459.      Releases the heap space used by the buffer. You can  release 
  460. the  buffer  space at anytime. If the buffer is  deallocated  the 
  461. next  time  you  try to use it, then  it  will  be  automatically 
  462. reallocated  to the default size. If the buffer number  given  is 
  463. invalid the function will return false.
  464.  
  465.  
  466.  
  467.  
  468. SetImagePath(Path:string):boolean
  469.  
  470.      You  can  specify that the images be placed  in  a  separate 
  471. subdirectory  by using this function. It is recommended that  you 
  472. place images in a separate directory if you are saving more  than 
  473. a couple of images to keep directory clutter to a minimum. If the 
  474. Path  could not be found, then the subdirectory will be made.  If 
  475. the subdirectory could not be made, then the function will return 
  476. false. You can preceed the path with a drive letter to direct the 
  477. image  to another drive. When specifying a new path, do  not  use 
  478. the  trailing  '\' SDImage will handle that. Example: 'D:\SDI'.
  479. You  can use the default drive by dropping the drive  letter  and 
  480. colon from the path designation.
  481.  
  482.  
  483.  
  484.  
  485. SaveImage(Img,Buf:word; x1,y1,x2,y2:integer; Style:word):boolean
  486.  
  487.      Use  this  function to save an image to  the  buffer  and/or 
  488. disk.  "Img" specifies the Img reference number, "Buf"  specifies 
  489. the buffer to use, "x1,y1,x2,y2" specifies the area of the screen 
  490. to  save,  and "Style" specifies how to save the  image.  If  the 
  491. Image could not be saved, then SaveImage will return false.
  492.  
  493.  
  494.  
  495.  
  496. DisplayImage(Img,Buf:word; ImgClr:boolean):boolean
  497.  
  498.      Use this function to display the image. "Img" specifies  the 
  499. image  reference  number to find. "Buf" specifies the  buffer  to 
  500. use, and ImgClr specifies whether to delete the image after it is 
  501. used. If ImgClr is false, then the image will not be deleted  and 
  502. DisplayImage  can  refer  to it again at a  later  date.  If  the 
  503. specified  image  is  not found, then  DisplayImage  will  return 
  504. false.
  505.  
  506.  
  507.  
  508.  
  509. FlushImage(Buf:word):boolean
  510.  
  511.      Flushes  an  image to disk from the buffer if  there  is  an 
  512. image in the buffer. You can use this before changing a buffer to 
  513. insure that no images are lost. If the image could not be flushed 
  514. (such as due to a disk error), the function will return false.
  515.  
  516.  
  517.  
  518.  
  519. DeleteImage(Img,Buf:word):boolean
  520.  
  521.      This  deletes an image from the buffer and/or disk.  If  the 
  522. specified image was not found the function will return false.
  523.  
  524.  
  525.  
  526.  
  527. <eof>
  528.